use std::collections::HashMap;
use std::error::Error;
use bytes::BytesMut;

pub trait Encode {
    fn encode(&self, buf: &mut BytesMut);
}

pub trait Decode {
    fn decode(&mut self, buf: &mut BytesMut) -> Result<(), Box<dyn Error>>;
}

#[derive(Debug, Default)]
pub struct Login {}
impl Encode for Login {
    fn encode(&self, buf: &mut BytesMut) {

    }
}

impl Decode for Login {
    fn decode(&mut self, buf: &mut BytesMut) -> Result<(), Box<dyn Error>> {
        todo!()
    }
}

#[derive(Debug, Default)]
pub struct LoginResp {}

impl Encode for LoginResp {
    fn encode(&self, buf: &mut BytesMut) {

    }
}
impl Decode for LoginResp {
    fn decode(&mut self, buf: &mut BytesMut) -> Result<(), Box<dyn Error>> {
        todo!()
    }
}

#[derive(Debug, Default)]
pub struct TokenLogin {}
impl Decode for TokenLogin {
    fn decode(&mut self, buf: &mut BytesMut) -> Result<(), Box<dyn Error>> {
        todo!()
    }
}

#[test]
fn map_test() {
    enum FuncParam {
        One(Box<dyn Decode + 'static>),
    }

    // 定义返回类型枚举
    enum FuncResult {
        Dyn(Box<dyn Encode>),
    }

    // 定义可调用 trait
    trait Callable {
        fn call(&self, param: FuncParam) -> FuncResult;
    }

    // 为不同函数实现 Callable
    struct Function0<F>(F);

    // impl<F: Fn(Login) -> LoginResp> Callable for Function0<F> {
    //     fn call(&self, param: FuncParam) -> FuncResult {
    //         match param {
    //             FuncParam::One(p) => {
    //                 let tp = p;
    //                 let rt = (self.0)(tp);
    //                 FuncResult::Dyn(Box::new(rt))
    //             }
    //         }
    //     }
    // }

    let mut functions: HashMap<&str, Box<dyn Callable>> = HashMap::new();
    // 添加函数
    // functions.insert("get_answer", Box::new(Function0(login)));
    // functions.insert("to_string", Box::new(Function0(|x: i32| x.to_string())));

    // 调用函数
    if let Some(func) = functions.get("get_answer") {
        
    }
}

fn login(login: Login) -> LoginResp {
    LoginResp::default()
}